import axios from "axios";
import Vue from "vue";
import { parseToken, getRefreshToken } from "./token";
// axios 配置
// axios.defaults.timeout = 8000;
const service = axios.create({
  baseURL: "https://api.job.sunxinao.cn/", // url = base url + request url
  // withCredentials: true, // send cookies when cross-domain requests
  timeout: 5000 // request timeout
});
// Loading 实例
let loading;
function startLoading() {
  loading = Vue.prototype.$loading({
    lock: true,
    text: "加载中...",
    background: "rgba(0, 0, 0, 0.7)"
  });
}
function endLoading() {
  setTimeout(() => {
    loading.close();
  }, 200);
}
let needLoadingRequestCount = 0;

function showFullScreenLoading() {
  if (needLoadingRequestCount === 0) {
    startLoading();
  }
  needLoadingRequestCount++;
}

function tryHideFullScreenLoading() {
  if (needLoadingRequestCount <= 0) return;
  needLoadingRequestCount--;
  if (needLoadingRequestCount === 0) {
    endLoading();
  }
}

service.interceptors.request.use(
  config => {
    //当请求的api不是检查用户是否存在时，启动加载动画
    if (config.url !== "/reg/valid/suppress_xhr_error") {
      showFullScreenLoading();
    }
    //TODO 是否先进行判断是否过期在进行发请求
    let bearerToken = localStorage.getItem("bearerToken") || "";
    let refreshToken = localStorage.getItem("refreshToken") || "";
    if (config.headers["authorization"] === undefined) {
      if (config.url.endsWith("/refresh_token")) {
        config.headers["authorization"] = "Bearer " + refreshToken;
      } else if (bearerToken.length !== 0) {
        config.headers["authorization"] = bearerToken;
      }
    }
    return config;
  },
  error => {
    tryHideFullScreenLoading();
    return Promise.reject(error);
  }
);

// 添加响应拦截器
service.interceptors.response.use(
  response => {
    tryHideFullScreenLoading();
    if (response.headers["authorization"]) {
      localStorage.setItem("bearerToken", response.headers["authorization"]);
      let token = response.headers["authorization"].replace(/Bearer\s*/i, "");
      let jwt = parseToken(token);
      let userId = jwt["payload"]["sub"];
      localStorage.setItem("user_id", userId);
    }
    return response;
  },
  async error => {
    tryHideFullScreenLoading();
    let response = error.response;
    if (response && response.status === 401) {
      // 当前会话已失效，删除 token 以进入匿名状态
      localStorage.removeItem("bearerToken");
      localStorage.removeItem("user_id");

      if (response.data && response.data["error"] === "invalid_token") {
        let refreshToken = localStorage.getItem("refreshToken") || "";
        if (refreshToken.length !== 0) {
          // 尝试刷新 token
          let refreshToken = await getRefreshToken();
          localStorage.setItem("refreshToken", refreshToken);
          if (refreshToken.length !== 0) {
            // FIXME 刷新成功的话重新发请求 （待测试）
            try {
              delete response.config.headers["authorization"];
              return await axios(response.config);
            } catch (e) {
              //会话刷新失败
              Vue.prototype
                .$confirm(
                  "未登录或会话失效，您可以取消停留在此页面，或重新登录",
                  "提示",
                  {
                    confirmButtonText: "确定",
                    cancelButtonText: "取消",
                    type: "warning"
                  }
                )
                .then(() => {
                  Vue.prototype.$router.push("/login");
                })
                .catch(() => {
                  location.reload();
                });
              return Promise.reject(e);
            }
          } else {
            //未登录
            Vue.prototype
              .$confirm(
                "未登录或会话失效，您可以取消停留在此页面，或重新登录",
                "提示",
                {
                  confirmButtonText: "确定",
                  cancelButtonText: "取消",
                  type: "warning"
                }
              )
              .then(() => {
                Vue.prototype.$router.push("/login");
              })
              .catch(() => {
                location.reload();
              });
          }
        }
      }
    }
    // Vue.prototype.$message({
    //   message: error.response.data.message || "",
    //   type: "error",
    //   duration: 5 * 1000
    // });

    //TODO 进行状态码逐一判断,通知嫚 报错信息要自己处理


    return Promise.reject(error);
  }
);
export default service;
